#include "event.h"
#include "base-structure/linux-list.h"
#include "event-internal.h"

#include <stdlib.h>
#include <assert.h>

/* #ifdef HAVE_EPOLL */
const struct eventop epollops;
/* #endif */

static const struct eventop *eventops[] = {
/* #ifdef HAVE_EPOLL */
    &epollops,
/* #endif */
    NULL
};

struct event_base *
event_base_new()  {
    struct event_base *base;

    base = calloc(1, sizeof(struct event_base));
    if (base == NULL) {
        return NULL;
    }

    for (int i = 0; eventops[i] && base->evbase == NULL; i++) {
        base->evsel = eventops[i];
        base->evbase = base->evsel->init(base);
    }
    if (base->evbase == NULL) {
        return NULL;
    }

    INIT_LIST_HEAD(&base->active_head);

    return base;
}

void event_active(struct event *ev, int res) {
    struct event_base *base;

    base = ev->base;
    assert(base);

    list_add_tail(&ev->active, &base->active_head);
}

 void event_set(struct event* ev, struct event_base *base,
                      int fd, short events,
                      void (*callback)(int, short, void *), void *args) {

     ev->ev_fd = fd;
     ev->ev_events = events;
     ev->base = base;
     ev->cb = callback;
     ev->args = args;

     INIT_LIST_HEAD(&ev->active);
 }

 void event_base_loop(struct event_base *base) {
     struct event *ev;
     while (1) {
         base->evsel->dispatch(base->evbase, base);
         while (!list_is_empty(&base->active_head)) {
             ev = list_entry(base->active_head.next, struct event, active);
             list_del(&ev->active);
             ev->cb(ev->ev_fd, ev->ev_events, ev->args);
         }
     }
 }

int event_add(struct event *ev) {
    return  ev->base->evsel->add(ev->base->evbase, ev);
}
